/*    
    OpenMheg - A free MHEG-5 library
    Copyright (C) 2008 Dharmesh Malam

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using Core.Model.Data.Generics;
using Core.Model.Data.Type;
using Parser;

namespace XMHEGDecoder.Builders
{
    public static class GenericVariableBuilder
    {

        public static Generic Build ( XmlElement node )
        {
            Generic ret;

            if ( node.Name == "new-generic-octetstring" )
            {
                ret = BuildGenericOctetString( node );
            }
            else if ( node.Name == "new-generic-integer" )
            {
                ret = BuildGenericInteger( node );
            }
            else if ( node.Name == "new-generic-boolean" )
            {
                ret = BuildGenericBoolean( node );
            }
            else if ( node.Name == "new-generic-content-reference" )
            {
                ret = BuildGenericContentRef( node );
            }
            else if ( node.Name == "new-generic-object-reference" )
            {
                ret = BuildGenericObjectRef( node );
            }
            else
                throw new Exception( "Unkown Generic" );

            return ret;

        }

        public static GenericBoolean BuildGenericBoolean ( XmlElement node )
        {
            GenericBoolean genericBoolean;

            XmlElement direct = node ["boolean"];
            XmlElement indirect = node ["indirect-reference"];
            if ( direct != null )
            {
                genericBoolean = new GenericBoolean( DecodeUtils.ParseBool( direct.InnerText ) );

            }
            else if ( indirect != null )
            {
                genericBoolean = new GenericBoolean( ObjectRefBuilder.Build( indirect ) );
            }
            else
                throw new Exception( "Unknown genereic boolean" );

            return genericBoolean;
        }

        public static GenericInteger BuildGenericInteger ( XmlElement node )
        {
            GenericInteger ret;

            XmlElement direct = node ["integer"];
            XmlElement indirect = node ["indirect-reference"];
            if ( direct != null )
            {
                ret = new GenericInteger( DecodeUtils.ParseInt( direct.InnerText ) );

            }
            else if ( indirect != null )
            {
                ret = new GenericInteger( ObjectRefBuilder.Build( indirect ) );
            }
            else
                throw new Exception( "Unknown genereic integer" );

            return ret;
        }

        public static GenericOctetString BuildGenericOctetString ( XmlElement node )
        {
            GenericOctetString genericOctetString;

            XmlElement direct = node ["octetstring"];
            XmlElement indirect = node ["indirect-reference"];

            if ( direct != null )
            {
                genericOctetString = new GenericOctetString( DecodeUtils.ParseStringFromNode( direct) );

            }
            else if ( indirect != null )
            {
                genericOctetString = new GenericOctetString( ObjectRefBuilder.Build( indirect ) );
            }
            else
                throw new Exception( "Unknown genereic octet string" );

            return genericOctetString;
        }

        public static GenericObjectRef BuildGenericObjectRef ( XmlElement node )
        {
            GenericObjectRef genericObjectRef;

            XmlElement direct = node ["direct-reference"];
            XmlElement indirect = node ["indirect-reference"];

            if ( direct != null )
            {
                genericObjectRef = new GenericObjectRef(ObjectRefBuilder.Build( direct ), null );

            }
            else if ( indirect != null )
            {
                genericObjectRef = new GenericObjectRef(null ,  ObjectRefBuilder.Build( indirect ) );
            }
            else
                throw new Exception( "Unknown GenericObjectRef" );

            return genericObjectRef;

        }

        public static GenericContentRef BuildGenericContentRef ( XmlElement node )
        {

            GenericContentRef genericContentRef;

            XmlElement direct = node ["content-reference"];
            XmlElement indirect = node ["indirect-reference"];

            if ( direct != null )
            {
                genericContentRef = new GenericContentRef( new ContentRef( DecodeUtils.DecodeBase64( direct.InnerText ) ) );

            }
            else if ( indirect != null )
            {
                genericContentRef = new GenericContentRef( ObjectRefBuilder.Build( indirect ) );
            }
            else throw new Exception( "Unknown generic Content ref" );
            
            return genericContentRef;
        }
    }
}

